 
package com.zdkj.admin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdkj.admin.api.dto.RoleChangeApproveDTO;
import com.zdkj.admin.api.dto.RoleChangeCreateDTO;
import com.zdkj.admin.api.dto.RoleChangeQueryDTO;
import com.zdkj.admin.api.entity.*;
import com.zdkj.admin.mapper.SysRoleChangeMapper;
import com.zdkj.admin.service.*;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.core.exceltools.ExcelUtil;
import com.zdkj.common.core.exceltools.IExcelParser;
import com.zdkj.common.core.exceltools.MultipartFileToFile;
import com.zdkj.common.core.exceltools.impl.CommonExcelParse;
import com.zdkj.common.core.exception.CheckedException;
import com.zdkj.common.data.datascope.DataScope;
import com.zdkj.common.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.List;

/**
 * 权限变更申请表
 *
 * @author haonan
 * @date 2020-01-13 17:07:11
 */
@Service
@Slf4j
public class SysRoleChangeServiceImpl extends ServiceImpl<SysRoleChangeMapper, SysRoleChange> implements SysRoleChangeService {

    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysDeptService sysDeptService;

    @Override
    public Boolean saveBatchWithExcel(File excelFile) throws Exception {
        String currentUser = SecurityUtils.getUser().getNikeName();
        Workbook workbook = ExcelUtil.chooseWorkbook(excelFile);
        Sheet sheet=workbook.getSheetAt(0);
        IExcelParser excelParser=new CommonExcelParse();
        List<SysRoleChange> sysRoleChanges = excelParser.parse(sheet,new SysRoleChange());
        if(CollectionUtil.isNotEmpty(sysRoleChanges)){
            for(SysRoleChange sysRoleChange:sysRoleChanges){
                sysRoleChange.setCreateUser(currentUser);
                sysRoleChange.setStatus(CommonConstants.APPROVE_TO_DO);
            }
            //刪除緩存文件
            MultipartFileToFile.delteTempFile(excelFile);
            return this.saveBatch(sysRoleChanges);
        }else{
            return false;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean approve(RoleChangeApproveDTO roleChangeApproveDTO) {

        List<SysRoleChange> sysRoleChanges = (List<SysRoleChange>) this.listByIds(roleChangeApproveDTO.getIdList());

        for(SysRoleChange sysRoleChange : sysRoleChanges){
            SysUser sysUser = sysUserService.getOne(Wrappers.<SysUser>query().lambda()
                    .eq(SysUser::getUserCode,sysRoleChange.getUserCode()));

            SysRole sysRole = sysRoleService.getOne(Wrappers.<SysRole>query().lambda()
                    .eq(SysRole::getRoleName,sysRoleChange.getNewRole()));

            //同意 -> 变更角色
            if(CommonConstants.APPROVE_AGREE.equals(roleChangeApproveDTO.getStatus())){
                //delete old role
                sysUserRoleService.remove(Wrappers.<SysUserRole>update().lambda()
                        .eq(SysUserRole::getUserId, sysUser.getUserId()));

                //insert new role
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(sysUser.getUserId());
                userRole.setRoleId(sysRole.getRoleId());
                userRole.insert();
            }

            sysRoleChange.setCheckedUser(SecurityUtils.getUser().getNikeName());
            sysRoleChange.setCheckerRemark(roleChangeApproveDTO.getCheckerRemark());
            sysRoleChange.setStatus(roleChangeApproveDTO.getStatus());
        }

        return this.updateBatchById(sysRoleChanges);
    }

    @Override
    public Boolean saveWithCheck(RoleChangeCreateDTO roleChangeCreateDTO) {

        //find user
        SysUser sysUser = checkUser(roleChangeCreateDTO.getUserId());
        //find old role
        List<SysRole> roleList = sysRoleService.findRolesByUserId(sysUser.getUserId());
        //check old role
        checkOldRole(roleChangeCreateDTO.getOldRole(),roleList);
        //check new role
        checkRole(roleChangeCreateDTO.getNewRole());

        //find dept
        SysDept sysDept = sysDeptService.getById(sysUser.getDeptId());

        //create sysRoleChange obj
        SysRoleChange sysRoleChange = new SysRoleChange();

        //set prop
        sysRoleChange.setUserName(sysUser.getNikename());
        sysRoleChange.setUserCode(sysUser.getUserCode());
        sysRoleChange.setDept(sysDept.getName());
        if(sysUser.getBelongToLine()){
            sysRoleChange.setLineName(roleChangeCreateDTO.getLineName());
            sysRoleChange.setStation(roleChangeCreateDTO.getStation());
        }

        sysRoleChange.setCreateUser(SecurityUtils.getUser().getNikeName());
        sysRoleChange.setStatus(CommonConstants.APPROVE_TO_DO);
        sysRoleChange.setOldRole(roleChangeCreateDTO.getOldRole());
        sysRoleChange.setNewRole(roleChangeCreateDTO.getNewRole());
        sysRoleChange.setRemark(roleChangeCreateDTO.getRemark());
        sysRoleChange.setDeptId(sysDept.getDeptId());

        return this.save(sysRoleChange);
    }

    /**check role name is match*/
    private void checkOldRole(String oldRole, List<SysRole> roleList) {
        //地跌项目目前账号只匹配单角色
        SysRole sysRole = roleList.get(0);
        if(!oldRole.equals(sysRole.getRoleName())){
            log.error("old role Name {} not match user role {}",oldRole,sysRole.getRoleName());
            throw new CheckedException("角色名称"+ oldRole+ "与原有角色不匹配" + sysRole.getRoleName());
        }
    }

    @Override
    public IPage queryByDataScope(Page page, RoleChangeQueryDTO roleChangeQueryDTO) {
        return this.baseMapper.queryByDataScope(page, roleChangeQueryDTO,new DataScope());
    }


    /**check get user obj*/
    private SysUser checkUser(Integer userId){
        SysUser sysUser = sysUserService.getById(userId);
        if(ObjectUtil.isEmpty(sysUser)){
            log.error("user id {} not exist",userId);
            throw new CheckedException("用户id不存在： "+userId);
        }
        return sysUser;
    }

    private SysUser checkUserByName(String name){
        SysUser sysUser = sysUserService.getOne(new QueryWrapper<SysUser>()
                .eq("username",name));

        if(ObjectUtil.isEmpty(sysUser)){
            log.error("user  {} not exist",name);
            throw new CheckedException("用户不存在： "+name);
        }
        return sysUser;
    }

    /**check role obj exist*/
    private SysRole checkRole(String roleName){
        SysRole sysRole = sysRoleService.getOne(new QueryWrapper<SysRole>()
                .eq("role_name",roleName));

        if(ObjectUtil.isEmpty(sysRole)){
            throw new CheckedException("角色不存在"+roleName);
        }
        return sysRole;
    }
}
